大概会用一个系列,讲一下面试过程中经常会问的一些问题,以及我觉得应该可以怎么回答。
当然,我的回答也并不是标准答案,只是我自己的一些理解,也欢迎其他人发表自己的想法。
作为本系列的第一篇文章,就先讲讲被问的最多的 js 继承
问题,但是应该不会写原型链相关的东西,
先列举一个最简单的问题:
写一个inherit(superClass, subClass)
方法,实现subClass
继承superClass
题目隐含的内容
继承有哪些特征,如何检测一个继承是否成功?
- 子类可以使用父类的方法和属性
- 子类可以自定义方法和属性,但应该不影响父类和其他继承同一个父类的子类
- 子类的原型链上可以找到父类(子类的__proto__应指向父类)
- 子类的实例可以通过
foo instanceof superClass
测试
常见的解法
es5
function inherit(p, s) {
s.prototype = Object.create(p.prototype, {
constructor: {
value: s,
enumerable: false,
writebale: true,
configurable: true
}
})
Object.setPrototypeOf ? Object.setPrototypeOf(s, p) : s.__proto__ = p
}
es4
function inherit(p, s) {
var f = new Function ()
f.prototype = new p()
var r = new f()
s.prototype = r
s.prototype.constructor = s
s.__proto__ = p
f = null
}
引申的问题:
-
Object.create
是什么?怎么使用?
Object.create(proto, [propertiesObject])
Object.create
提供了一个创建对象的方法,使用现有的对象作为新创建对象的__proto__
,同时可以传入添加到新对象的可枚举属性, 这些属性可以对应到Object.defineProperties
的第二个参数中。
返回值为所创建的新对象.
例如:
s.prototype = Object.create(f.prototype, {
constructor: {
value: s,
enumberable: false,
writealble: true,
configurale: true
}
})
-
Object.defineProperties
是什么?怎么使用?可以列举一个Object.definProperties
的实际应用吗?
Object.defineProperties
可以直接在一个对象上定义或修改属性,并返回该对象。
例如:
target = Object.defineProperties(target, props)
本质上 Object.defineProperties
是对Object.defineProperty
的集中调用,可以理解为是Object.definePeropety
的复数版。
Object.defineProperty
的使用方法为:
target = Object.defineProperty(target, prop, descriptor)
所以本质上Object.defineProperties
就是如下代码:
Object.keys(props).forEach(function (prop) {
let descriptor = props[prop]
Object.defineProperty(target, prop, descriptor)
})
其中 descriptor
的可选值有以下集中:
- configurable: 当且仅当该属性的 configurable 为
true
时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false
。 - enumerable: 当且仅当该属性的enumerable为
true
时,该属性才能够出现在对象的枚举属性中。默认为false
。 - value: 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为
undefined
- writable: 当且仅当该属性的writable为true时,value才能被赋值运算符改变。默认为 false。
- get: 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。该方法返回值被用作属性值。默认为
undefined
。 - set: 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为
undefined
。
如果一个 descriptor 不具有 value
, writebale
, get
和 set
任意一个关键字,那么将会被认为是一个数据描述符。
如果一个描述符同时具有(value
或writbale
)和(get
或set
),将会产生一个异常.
- 继承多个父类怎么做?
继承多个父类的话,可以使用 Object.assign
方法。
例如:
targe = Object.assign({}, superClassA, superClassB, ...)
但是继承多个父类的话,子类就不能通过 son instanceof superClass
这样的验证了.
-
Object.assign
是什么?怎么用?用的时候有哪些需要注意?
Object.assign
方法用于将所有可枚举属性从一个或多个源对象复制到目标对象,并返回目标对象,例如:
target = Object.assign(target, source)
如果具有同名属性,那么在后面对象中的属性,将会覆盖目标对象中的属性。
需要注意以下几点:
- 继承属性和不可枚举属性是不能拷贝的。
- 原始类型会被包装为对象,
null
,undefined
会被忽略,并且只有字符串的包装对象才可能有自身可枚举的属性. - 可以拷贝
symbol
类型的属性
-
Object.assign
会调用setter
和getter
吗?调用的是哪里的setter
和getter
?
Object.assign
会调用源对象的 getter
,并把源对象的 getter
的返回值当做新对象的该属性的值。setter
则是会直接加在新创建的对象中,而不会沿用源对象的 setter
.
-
Object.getOwnPropertyDescriptor
是什么?主要用来做什么?
Object.getOwnPropertyDescriptor
返回直到对象上一个自有属性对应的描述符,例如:
Object.getOwnPropertyDescriptor(obj, prop)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。